//
//  RBPagerView.m
//  RBDemoProj
//
//  Created by Lan on 2019/3/15.
//  Copyright © 2019 SummerTea. All rights reserved.
//

#import "RBPagerView.h"
#import "RBPagerHeaderModel.h"
#import "NSObject+YYAdd.h"
#import "RBDefine.h"
#import <UIView+YYAdd.h>
#import <Masonry.h>

static NSString *const RB_PAGER_OFFSET_KEY = @"contentOffset";
static char *const RB_PAGER_ADJUST_KEY = "RB_PAGER_ADJUST_KEY";

@interface RBPagerView()<RBPagerScrollViewDelegate>

@property(nonatomic, strong) RBPagerHeaderModel *model;

/** 悬浮视图 */
@property(nonatomic, strong) UIView *floatView;
@property(nonatomic, strong) RBPagerHeaderView *pagerHeaderView;
@property(nonatomic, strong) RBPagerScrollView *pagerContentView;

@property(nonatomic, strong) UIScrollView *currentScrollView;

@property(nonatomic, assign) CGFloat floatViewHeight;
@property(nonatomic, assign) CGFloat headerViewHeight;
@property(nonatomic, assign) CGFloat headerStickTop;
@property(nonatomic, assign) CGFloat headerBottom;

@end

@implementation RBPagerView

#pragma mark - Lifecycle

- (void)dealloc
{
    @try
    {
        [self.currentScrollView removeObserver:self forKeyPath:RB_PAGER_OFFSET_KEY];
    }
    @catch (NSException *exception)
    {
        
    }
    @finally
    {
        
    }
}

#pragma mark - Private

- (UIScrollView *)scrollViewWithVc: (UIViewController *)vc
{
    UIScrollView *scrollView = nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    //如果想自己指定一个view,实现下rbDesScrollView
    if ([vc respondsToSelector:@selector(rbDesScrollView)])
    {
        scrollView = [vc performSelector:@selector(rbDesScrollView)];
    }
#pragma clang diagnostic pop
    else if ([vc.view isKindOfClass:[UIScrollView class]])
    {
        scrollView = (UIScrollView *)vc.view;
    }
    else
    {
        for (UIView *view in vc.view.subviews)
        {
            if ([view isKindOfClass:[UIScrollView class]])
            {
                scrollView = (UIScrollView *)view;
                break;
            }
        }
    }
    return scrollView;
}

- (void)adjustSubViews
{
    CGFloat maxY = CGRectGetMaxY(self.floatView.frame);
    self.pagerContentView.topPadding = maxY;
}

- (void)changeYProgress
{
    if (self.yProgressBlock)
    {
        CGFloat progress = self.floatView.top/(self.floatViewHeight - self.headerViewHeight - self.headerStickTop - self.headerBottom);
        self.yProgressBlock(ABS(progress));
    }
}

#pragma mark - Public

- (void)setupWithModel: (RBPagerHeaderModel *)model;
{
    self.backgroundColor = [UIColor whiteColor];
    self.model = model;
    self.pagerHeaderView.hidden = NO;
    self.pagerContentView.hidden = NO;
    [self bringSubviewToFront:self.floatView];
    
    if (model.selectedIndex)
    {
        [self.pagerContentView scrollToPageAtIndex:model.selectedIndex animated:YES];
    }
    else
    {
        [self pagerScrollView:self.pagerContentView didScrollToIndex:model.selectedIndex];
    }
}

- (void)configWithHeaderStickTop: (CGFloat)headerStickTop
                    headerBottom: (CGFloat)headerBottom
                    headerHeight: (CGFloat)headerHeight
                 floatViewHeight: (CGFloat)floatViewHeight
{
    self.headerStickTop = headerStickTop;
    self.headerBottom = headerBottom;
    self.headerViewHeight = headerHeight;
    self.floatViewHeight = floatViewHeight;
}

- (void)reloadWithHeaderStickTop: (CGFloat)headerStickTop
                    headerBottom: (CGFloat)headerBottom
                    headerHeight: (CGFloat)headerHeight
                 floatViewHeight: (CGFloat)floatViewHeight
{
    self.headerStickTop = headerStickTop;
    self.headerBottom = headerBottom;
    self.headerViewHeight = headerHeight;
    self.floatViewHeight = floatViewHeight;
    self.floatView.height = self.floatViewHeight;
    self.currentScrollView.contentOffset = CGPointMake(self.currentScrollView.contentOffset.x, self.currentScrollView.contentOffset.y+0.1);
}

#pragma mark - Public

#pragma mark - Event

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if ([keyPath isEqualToString:RB_PAGER_OFFSET_KEY])
    {
        if (object != self.currentScrollView)
        {
            return;
        }
        if ([[(UIScrollView *)object getAssociatedValueForKey:RB_PAGER_ADJUST_KEY] boolValue])
        {
            return;
        }
        if ([[self.currentScrollView getAssociatedValueForKey:RB_PAGER_ADJUST_KEY] boolValue])
        {
            return;
        }
        
//        NSLog(@"change");
        CGPoint oldPoint = [[change objectForKey:NSKeyValueChangeOldKey] CGPointValue];
        CGPoint newPoint = [[change objectForKey:NSKeyValueChangeNewKey] CGPointValue];
        
        CGFloat insetTop = self.currentScrollView.contentInset.top;
        
        CGFloat maxY = 0;
        CGFloat minY = self.headerViewHeight + self.headerStickTop + self.headerBottom - self.floatViewHeight;
        if (oldPoint.y > newPoint.y)
        {//下划
            if (newPoint.y + insetTop < 0 && self.floatView.top < 0)
            {
                CGFloat desY = self.floatView.top - (newPoint.y - oldPoint.y);
                desY = MAX(minY, desY);
                desY = MIN(maxY, desY);
                
                [self.currentScrollView setAssociateValue:@(YES) withKey:RB_PAGER_ADJUST_KEY];
                
                self.currentScrollView.contentOffset = oldPoint;
                self.floatView.top = desY;
                [self changeYProgress];
                [self adjustSubViews];
                
                [self.currentScrollView setAssociateValue:@(NO) withKey:RB_PAGER_ADJUST_KEY];
            }
            else
            {
                
            }
        }
        else
        {//上划
            //屏蔽下拉刷新
            if (newPoint.y < -insetTop || oldPoint.y < -insetTop)
            {
                return;
            }
            //floatview往上走
            CGFloat desY = self.floatView.top - (newPoint.y - oldPoint.y);
            desY = MAX(minY, desY);
            desY = MIN(maxY, desY);
            
            //还没到顶,移动floatview
            if (self.floatView.top > minY)
            {
                [self.currentScrollView setAssociateValue:@(YES) withKey:RB_PAGER_ADJUST_KEY];
                
                self.currentScrollView.contentOffset = oldPoint;
                self.floatView.top = desY;
                [self changeYProgress];
                [self adjustSubViews];
                
                [self.currentScrollView setAssociateValue:@(NO) withKey:RB_PAGER_ADJUST_KEY];
            }
        }
    }
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    self.currentScrollView.panGestureRecognizer.enabled = YES;
    UIView *view = [super hitTest:point withEvent:event];
    if(self.currentScrollView)
    {
        //手势添加到A,自然会从B移除
        if ([self convertPoint:self.pagerHeaderView.frame.origin fromView:self.pagerHeaderView.superview].y == self.headerStickTop)
        {//划到最上面,不让header响应上下拖动
            [self.currentScrollView addGestureRecognizer:self.currentScrollView.panGestureRecognizer];
        }
        else if (CGRectContainsPoint(self.floatView.frame, point))
        {
            [view addGestureRecognizer:self.currentScrollView.panGestureRecognizer];
        }
        else
        {
            [self.currentScrollView addGestureRecognizer:self.currentScrollView.panGestureRecognizer];
        }
    }
    return view;
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //想屏蔽一下拖动上面,下面刷新,不太成
    UITouch *touch = [touches anyObject];
    if (touch.view != self.currentScrollView)
    {
        CGPoint currentPoint = [touch locationInView:touch.view];
        CGPoint lastPoint = [touch previousLocationInView:touch.view];
        if (self.floatView.top >= 0 && currentPoint.y - lastPoint.y > 0)
        {
            //已然不怎么好使,
            self.currentScrollView.panGestureRecognizer.enabled = NO;
        }
    }
}

#pragma mark - UIPagerScrollViewDelegate

- (NSInteger)numberOfPagesInPagerScrollView:(RBPagerScrollView *)pagerScrollView
{
    return self.pagerHeaderView.model.titles.count;
}

- (UIView *)pagerScrollView:(RBPagerScrollView *)pagerScrollView contentViewAtIndex:(NSInteger)index didEndDecelerating:(BOOL)endDecelerating didEndScrollingAnimation:(BOOL)endScrollingAnimation
{
    UIViewController *vc = self.getVcBlock(index);
    return vc.view;
}

- (void)pagerScrollView:(RBPagerScrollView *)pagerScrollView didScrollToIndex:(float)index
{
    [self.pagerHeaderView scrollToVisibleAtIndex:index];
    [self.pagerHeaderView scrollBottomLineToIndex:index];
    [self.pagerHeaderView setButtonSelectedAtIndex:index];
    
    [self adjustSubViews];
    
    NSInteger currentIndex = roundf(index);
    if (ABS(currentIndex - index) > 0.001)
    {
        return;
    }
    UIViewController *vc = self.getVcBlock(currentIndex);
    UIScrollView *scrollView = [self scrollViewWithVc:vc];
    if (self.currentScrollView != scrollView)
    {
        @try
        {
            [self.currentScrollView removeObserver:self forKeyPath:RB_PAGER_OFFSET_KEY];
        }
        @catch (NSException *exception)
        {
        }
        @finally
        {
        }
        self.currentScrollView = scrollView;
        [self.currentScrollView addObserver:self forKeyPath:RB_PAGER_OFFSET_KEY options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
    }
}

#pragma mark - Setter

- (void)setIgnoreHorizontalScroll:(BOOL)ignoreHorizontalScroll
{
    _ignoreHorizontalScroll = ignoreHorizontalScroll;
    if (_pagerContentView)
    {
        _pagerContentView.scrollEnabled = !ignoreHorizontalScroll;
    }
}

#pragma mark - Getter

- (UIView *)floatView
{
    if (!_floatView)
    {
        self.floatView = ({
            UIView *view = [UIView new];
            view.backgroundColor = [UIColor lightGrayColor];
            view.width = kRBMainScreenWidth;
            view.top = 0;
            view.left = 0;
            view.height = self.floatViewHeight;
            [self addSubview:view];
            view;
        });
    }
    return _floatView;
}

- (RBPagerHeaderView *)pagerHeaderView
{
    if (!_pagerHeaderView)
    {
        self.pagerHeaderView = ({
            RBPagerHeaderView *view = [RBPagerHeaderView new];
            
            view.model = self.model;
            __weak typeof(self) weak_self = self;
            view.btnEventBlock = ^(NSInteger index, UIButton *btn) {
                [weak_self.pagerContentView scrollToPageAtIndex:index animated:NO];
                [weak_self.pagerHeaderView scrollBottomLineToIndex:index];
                [weak_self.pagerHeaderView scrollToVisibleAtIndex:index];
            };
            [self.floatView addSubview:view];
            [view mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.mas_equalTo(0);
                make.bottom.mas_equalTo(-self.headerBottom);
                make.right.mas_equalTo(0);
                make.height.mas_equalTo(self.headerViewHeight);
            }];
            
            view;
        });
    }
    return _pagerHeaderView;
}

- (RBPagerScrollView *)pagerContentView
{
    if (!_pagerContentView)
    {
        self.pagerContentView = ({
            RBPagerScrollView *view = [RBPagerScrollView new];
            view.showsHorizontalScrollIndicator = NO;
            view.showsVerticalScrollIndicator = NO;
            view.pagerDelegate = self;
            view.scrollEnabled = !self.ignoreHorizontalScroll;
            view.bounces = NO;
            [self addSubview:view];
            [view mas_makeConstraints:^(MASConstraintMaker *make) {
                make.edges.mas_equalTo(0);
            }];
            view;
        });
    }
    return _pagerContentView;
}

@end
